package com.demo.common.Interceptor;

import com.demo.common.util.JwtKit;
import com.demo.common.util.ResMsg;
import com.demo.module.system.service.SystemService;
import com.mi.rule.security.auth.Public;
import com.mi.rule.util.EnvKit;
import com.mi.rule.util.project.MiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 权限认证
 *
 * @author 王永吉
 */
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    private SystemService systemService;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object object) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "authorization,Authorization,Token,token,Auth,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type");


        if (request.getMethod().equals("OPTIONS")) return true;
        //response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        if (request.getRequestURI().equals("/error")) {
            return true;
        }


        try {
            //权限认证开关(默认为true在yml中配置)
            if (!EnvKit.enablePermission()) return true;

            //检查权限
            return hasResource(request, object);

        } catch (MiException e) {
            log.info("请求:{} 在拦截器中发生异常 ,{}", request.getRequestURI(), e.message);
            log.info(ExceptionUtils.getStackTrace(e));
            throw e;
        } catch (Exception e) {
            log.info(ExceptionUtils.getStackTrace(e));
            throw e;
        }
    }

    //校验权限
    private boolean hasResource(HttpServletRequest request, Object object) throws Exception {
        boolean isHandlerMethod = object instanceof HandlerMethod;
        if (isHandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) object;
            String requestURI = request.getRequestURI();

            //检查存在放行注解@Public,执行放行
            Public aPublic = handlerMethod.getMethod().getAnnotation(Public.class);
            if (aPublic == null) {
                aPublic = handlerMethod.getMethod().getDeclaringClass().getAnnotation(Public.class);
            }
            if (aPublic != null) {
                log.info("访问资源:{} , 存在@Public注解{},直接放行", requestURI, aPublic.value());
                return true;
            }

            //路由符合放行条件
            if (requestURI.contains("/public/") || requestURI.contains("static/") || requestURI.contains("/static/")) {
                log.info("{} 路由符合放行条件，直接放行", requestURI);
                return true;
            }

            //检查用户权限
            String token = request.getHeader("token");
            if (!JwtKit.check(token)) {
                log.info("{} Token已失效  Token: {}", requestURI, token);
                throw new MiException(ResMsg.ERROR_401);
            }
            systemService.checkAuthByToken(token, requestURI);

            //检查通过，放行
            return true;
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object,
                                Exception exception) {
        //        System.out.println("7777777777777777777777777777777777777");
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object,
                           ModelAndView modelAndView) {
        //        System.out.println("888888888888888888888888888888888888888888888888");
    }


}
